﻿using UnityEngine;
using System.Collections;
using GoCivil.Utils;
using System.Collections.Generic;

namespace MyAssetBundles {
    public class MyAssetManager : MonoSingleton<MyAssetManager> {
        protected MyAssetBundlesManager _myAssetBundles;
        protected Dictionary<string, MyAssetOperation> _assetOperationDic;
        void Awake ()
        {
            _myAssetBundles = gameObject.AddComponent<MyAssetBundlesManager>();
            _assetOperationDic = new Dictionary<string, MyAssetOperation>();
        }

        public IEnumerator Reset ()
        {
            yield return _myAssetBundles.Reset();
        }

        IEnumerator LoadAssetBundleAsyncCall (string assetBundleName, AssetBundle assetBundle)
        {
            List<string> keyList = new List<string>();
            foreach (var item in _assetOperationDic)
            {
                if (item.Value.assetBundleName == assetBundleName)
                    keyList.Add(item.Key);
            }

            MyAssetOperation asset = null;
            foreach (var key in keyList)
            {
                _assetOperationDic.TryGetValue(key, out asset);
                if (asset == null) continue;

                _assetOperationDic.Remove(key);
                if (assetBundle == null)
                {
                    asset.error = "without file";
                } else if (asset.operation == null)
                {
                    asset.operation = assetBundle.LoadAssetAsync(asset.assetName, asset.assetType);
                }

                yield return asset.RaiseEvent();
                asset.Destroy();
            }
        }

        void LoadAssetAsync<T> (string assetBundleName, string assetName, MyAssetHandler handler)
        {
            if (handler == null || assetBundleName.Length == 0 || assetName.Length == 0) return;
            string key = MyAssetOperation.GetKey(assetBundleName, assetName, typeof(T));
            MyAssetOperation asset = null;
            _assetOperationDic.TryGetValue(key, out asset);
            if (asset == null)
            {
                asset = new MyAssetOperation();
                asset.assetBundleName = assetBundleName;
                asset.assetName = assetName;
                asset.assetType = typeof(T);
                _assetOperationDic.Add(key, asset);
                _myAssetBundles.LoadAssetBundleAsync(assetBundleName, LoadAssetBundleAsyncCall);
            }
            asset.onEventMyAsset += handler;
        }

        public IEnumerator ReloadDependencies (List<string> nameList)
        {
            yield return _myAssetBundles.ReloadDependencies(nameList);
        }

        // 可用于预加载
        public static void LoadAssetBundleAsync (string assetBundleName, MyAssetBundleHandler handler)
        {
            Instance._myAssetBundles.LoadAssetBundleAsync(assetBundleName, handler);
        }

        // 异步加载资源,需手动释unload
        public static void LoadAsync (string assetBundleName, string assetName, MyAssetHandler handler)
        {
            LoadAsync<GameObject>(assetBundleName, assetName, handler);
        }

        public static void LoadAsync<T> (string assetBundleName, string assetName, MyAssetHandler handler)
        {
            Instance.LoadAssetAsync<T>(assetBundleName, assetName, handler);
        }

        // 异步加载资源,资源自动释放 
        public static void LoadAsyncAuto (string assetBundleName, string assetName, MyAssetHandler handler)
        {
            LoadAsyncAuto<GameObject>(assetBundleName, assetName, handler);
        }

        public static void LoadAsyncAuto<T> (string assetBundleName, string assetName, MyAssetHandler handler)
        {
            LoadAsync(assetBundleName, assetName, handler);
            Unload(assetBundleName);
        }

        // 卸载资源
        public static void Unload (string assetBundleName)
        {
            Instance._myAssetBundles.Unload(assetBundleName);
        }

        // 卸载所有无用资源
        public static void UnloadAllUnused ()
        {
            Instance._myAssetBundles.UnloadAllUnused();
        }
    }
}
